package chess;

import java.util.ArrayList;
import java.math.*;

public class GameState {
    private Board _board;
    private int _moveNumber; //even = white to move, odd = black to move
    private boolean _castleQW, _castleKW, _castleQB, _castleKB;

    public GameState() {
        _board = new Board();
        _moveNumber = 0;
        _castleQW = true;
        _castleKW = true;
        _castleQB = true;
        _castleKB = true;
    }

    public GameState(Board b) {
        _board = b;
        _moveNumber = 0;
        _castleQW = true;
        _castleKW = true;
        _castleQB = true;
        _castleKB = true;
    }

        public GameState(GameState gs) {
            _board = new Board(gs._board);
            _moveNumber = gs._moveNumber;
            _castleQW = gs._castleQW;
            _castleKW = gs._castleKW;
            _castleQB = gs._castleQB;
            _castleKB = gs._castleKB;
        }

    public ArrayList<Move> getAllLegalMoves() {
        boolean whiteToMove = (_moveNumber % 2 == 0);
        ArrayList<Move> unblocked = _board.getAllUnblockedMoves(!whiteToMove);
        //System.out.println("_---------------------_");
        for (int i = 0; i < unblocked.size(); i++) {
            //System.out.println(unblocked.get(i));
            if (!isLegalMove(unblocked.get(i))) {
                unblocked.remove(i);
            }
        }
        return unblocked;
    }
        //Precondition: move is "unblocked"
    public boolean isLegalMove(Move move) {
        int fromFile = move.fromFile();
        int fromRank = move.fromRank();
        int toFile = move.toFile();
        int toRank = move.toRank();
        Square piece = _board.getSquare(fromFile, fromRank);
        boolean whiteToMove = (_moveNumber % 2 == 0);

        if (piece.piece().isKing()) {
            if ((toFile - fromFile) == 2) {
                if (whiteToMove) {
                    if (!_castleKW) {
                        return false;
                    }
                } else {
                    if (!_castleKB) {
                        return false;
                    }
                }
            } else if ((toFile - fromFile) == -2) {
                if (whiteToMove) {
                    if (!_castleQW) {
                        return false;
                    }
                } else {
                    if (!_castleQB) {
                        return false;
                    }
                }
            }
        }

        Board temp = new Board(_board);
        temp.makeMove(move);
        return !temp.isInCheck(!whiteToMove);
    }

        public void makeMove(Move move) {
            int file = move.fromFile();
            int rank = move.fromRank();
            if (_castleKW) {
                if ((file == 4 && rank == 0) || (file == 7 && rank == 0)) {
                    _castleKW = false;
                }
            }
            if (_castleQW) {
                if ((file == 4 && rank == 0) || (file == 0 && rank == 0)) {
                    _castleQW = false;
                }
            }
            if (_castleKB) {
                if ((file == 4 && rank == 7) || (file == 7 && rank == 7)) {
                    _castleKB = false;
                }
            }
            if (_castleQB) {
                if ((file == 4 && rank == 7) || (file == 0 && rank == 7)) {
                    _castleQB = false;
                }
            }

            _board.makeMove(move);
            _moveNumber++;
        }

        public Board board() {
            return _board;
        }

        public boolean whiteToMove() {
            return _moveNumber % 2 == 0;
        }

        public String toString() {
            String result = _board.toString();
            result += _castleKW + " " + _castleQW + " " + _castleKB + " " + _castleQB + "\n";
            return result;
        }
}
